import {
  getHistory,
  deleteConversation,
  starConversation,
  unStarConversation
} from '@/api/chat'
import { DateTime } from 'luxon'
import PsMessage from '@/components/message/index'

const TIME_FORMAT_STR = 'yyyy-MM-dd'
// const t = (v) => {}

const __cache_history_list = {
  all: new Map(),
  search: new Map(),
  favorites: new Map()
}

/**
 * 复制生原生列表，没有经过proxy的数据
 * @param list
 * @returns
 */
function copyToOriginList (list) {
  const values = []
  for (const item of list) {
    const value = { ...item }
    value.list = []
    for (const item2 of item.list) {
      value.list.push({ ...item2 })
    }
    values.push(value)
  }
  return values
}

/**
 *  将列表数据按日期分类
 * @param {AiChat.HistoryItem[]} list
 * @return
 */
// eslint-disable-next-line sonarjs/cognitive-complexity
function groupByDate (list) {
  const now = new Date()
  const today = new Date(`${now.getFullYear()}/${now.getMonth() + 1}/${now.getDate()} 00:00:00`).getTime()
  const todayStr = DateTime.fromMillis(today).toFormat(TIME_FORMAT_STR)
  const yestodayTimestap = today - 24 * 60 * 60 * 1000
  const yestodayStr = DateTime.fromMillis(yestodayTimestap).toFormat(TIME_FORMAT_STR)

  const listMap = new Map()

  for (const item of list) {
    const date = DateTime.fromJSDate(new Date(item.last_message_at))
    const str = date.toFormat(TIME_FORMAT_STR)
    const strLocal = date.toFormat(TIME_FORMAT_STR)
    item.timeStr = date.toLocaleString({ hour: '2-digit', minute: '2-digit' })
    const dateStr = str === todayStr ? 'Today' : str === yestodayStr ? 'Yestoday' : str
    const dateLocal = str === todayStr ? `今天 ${str}` : str === yestodayStr ? `昨天 ${str}` : strLocal
    const timestamp = str === todayStr ? today : str === yestodayStr ? yestodayTimestap : date.toMillis()

    if (listMap.has(dateStr)) {
      listMap.get(dateStr).list.push(item)
    } else {
      listMap.set(dateStr, {
        date: dateStr,
        dateLocal,
        timestamp,
        list: [item]
      })
    }
  }
  return listMap
}

function combineGroup (list, key, after = true) {
  const data = __cache_history_list[key]

  if (data.size === 0) {
    __cache_history_list[key] = list
    return [...list.values()]
  }

  list.forEach((item) => {
    if (data.has(item.date)) {
      const method = after ? 'push' : 'unshift'
      data.get(item.date).list[method](...item.list)
    } else {
      data.set(item.date, item)
    }
  })

  // 按时间排序
  const result = [...data.values()]
  return copyToOriginList(result)
}

function deleteItemFromGroup (id, ls, type) {
  const list = ls
  if (list.length === 0) return list

  for (const item of list) {
    if (item.list.length === 0) continue
    const index = item.list.findIndex((i) => i.conversation_id === id)
    if (index !== -1) {
      item.list.splice(index, 1)
      if (item.list.length === 0) {
        list.splice(
          list.findIndex((i) => i.date === item.date),
          1
        )
        __cache_history_list[type].delete(item.date)
      }
      return list
    }
  }
  return list
}

// 更新列表里面的某个key的值
function updateItemKeyFromGroup (id, ls, value) {
  const { key, val } = value
  const list = ls
  if (list.length === 0) return list
  for (const item of list) {
    if (item.list.length === 0) continue
    const index = item.list.findIndex((i) => i.conversation_id === id)
    if (index === -1) continue
    item.list[index][key] = val
  }
  return list
}

// 更新新数据到收藏列表
function insertItemToFavorites (item) {
  const data = __cache_history_list.favorites
  const list = groupByDate([item])

  if (data.size === 0) {
    __cache_history_list.favorites = list
    return [...list.values()]
  }
  list.forEach((value) => {
    const insertItem = value.list[0]
    const insertItemTime = new Date(insertItem.last_message_at).getTime()
    if (data.has(value.date)) {
      const target = data.get(value.date)
      // 比对时间
      for (let i = 0; i < target.list.length; i++) {
        const targetTime = new Date(target.list[i].last_message_at).getTime()
        if (insertItemTime > targetTime) {
          // 插入到当前第i个数组的前面
          target.list.splice(i, 0, insertItem)
          return
        }
      }
      target.list.push(insertItem)
    } else {
      data.set(value.date, value)
    }
  })
  // 按时间排序
  const result = [...data.values()].sort((v1, v2) => v2.timestamp - v1.timestamp)
  return copyToOriginList(result)
}

const state = {
  historyStore: {
    show: false,
    activeType: 'all',
    all: [],
    favorites: [],
    search: [],
    editItem: {
      show: false,
      content: '',
      item: {}
    },
    showHistoryTips: false,
    count: 0
  }
}
const mutations = {
  SET_HISTORYSTORE (state, param) {
    state.historyStore = Object.assign({}, state.historyStore, param)
  }
}
const actions = {
  setStatus ({ commit, state }, val) {
    commit('SET_HISTORYSTORE', { show: val })
  },
  async getHistoryAll ({ commit, state }, opt) {
    const { data } = await getHistory(opt)
    const { conversations, count, code, msg = '' } = data
    if (code === 200) {
      const optype = opt.keyword ? 'search' : opt.is_star ? 'favorites' : 'all'
      if (opt.page === 1) {
        commit('SET_HISTORYSTORE', { [optype]: [] })
        __cache_history_list[optype].clear()
      }
      const values = groupByDate(conversations || [])
      const optypeS = combineGroup(values, optype)
      commit('SET_HISTORYSTORE', { [optype]: optypeS })
      const isEnd = conversations === null || conversations.length < (opt.page_size || 10)
      commit('SET_HISTORYSTORE', { activeType: optype, count: count })
      return { end: isEnd, count }
    }
    return { err: true, msg }
  },
  // 删除成功后清除本地数据
  deleteListItem ({ commit, state }, id) {
    const search = deleteItemFromGroup(id, state.historyStore.search, 'search')
    const favorites = deleteItemFromGroup(id, state.historyStore.favorites, 'favorites')
    const all = deleteItemFromGroup(id, state.historyStore.all, 'all')
    commit('SET_HISTORYSTORE', { all, search, favorites })
  },
  // 删除会话
  async requestDeleteListItem ({ commit, state, dispatch }, item) {
    const { data } = (await deleteConversation(
      item.conversation_id
    ))
    if (data.code === 200) {
      PsMessage({ message: '删除成功' })
      dispatch('deleteListItem', item.conversation_id)
      return true
    }
    PsMessage({ message: '删除失败, 请稍后再试' })
  },
  // 收藏或者取消收藏会话成功后更新本地数据
  updateStarListItem ({ commit, state }, { item, is_star }) {
    let favorites = []
    if (!is_star) {
      // 取消收藏,删除收藏列表的数据
      favorites = deleteItemFromGroup(item.conversation_id, state.historyStore.favorites, 'favorites')
    } else {
      const sub = { ...item, is_star: true }
      favorites = insertItemToFavorites(sub)
    }
    // 更新其他列表的数据
    const all = updateItemKeyFromGroup(item.conversation_id, state.historyStore.all, { key: 'is_star', val: is_star })
    const search = updateItemKeyFromGroup(item.conversation_id, state.historyStore.search, { key: 'is_star', val: is_star })
    commit('SET_HISTORYSTORE', { all, search, favorites })
  },
  // 收藏或者取消收藏对话
  async reuqestStarListItem ({ commit, state, dispatch }, item) {
    const is_star = !!item.is_star
    const service = is_star ? unStarConversation : starConversation
    const { data } = (await service(item.conversation_id))
    if (data.code === 200) {
      PsMessage({ message: is_star ? '取消收藏成功' : '收藏成功' })
      dispatch('updateStarListItem', { item, is_star: !is_star })
      return true
    }
    PsMessage({ message: '收藏失败,请稍后再试' })
    return false
  },
  clear ({ commit, state }) {
    commit('SET_HISTORYSTORE', { all: [], search: [], favorites: [] })
  },
  addHistory ({ commit, state }, { item, conversation_id, response }) {
    // if (state.historyStore.all.length <= 0) return
    const date = new Date().toISOString()
    const data = {
      conversation_id: conversation_id,
      created_at: date,
      is_star: false,
      last_message_at: date,
      title: item.content,
      first_msg_content: response
    }
    const values = groupByDate([data])
    commit('SET_HISTORYSTORE', { all: combineGroup(values, 'all', false) })
  },
  setEditItem ({ commit, state }, item) {
    commit('SET_HISTORYSTORE', { editItem: {
      show: true,
      item: item,
      content: item.title
    } })
  },
  hideEditItem ({ commit, state }) {
    commit('SET_HISTORYSTORE', { editItem: {
      show: false,
      item: {},
      content: ''
    } })
  },
  updateEditItem ({ commit, state }, { id, content }) {
    const all = updateItemKeyFromGroup(id, state.historyStore.all, { key: 'title', val: content })
    const search = updateItemKeyFromGroup(id, state.historyStore.search, { key: 'title', val: content })
    const favorites = updateItemKeyFromGroup(id, state.historyStore.favorites, { key: 'title', val: content })
    commit('SET_HISTORYSTORE', { all, search, favorites })
  },
  setHistoryTips ({ commit, state }, val) {
    commit('SET_HISTORYSTORE', { showHistoryTips: val })
  }
}
export default {
  namespaced: true,
  state,
  mutations,
  actions
}
